﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using PivotData;
using PivotWebsite.Controllers;
using System;
using System.Web.Http;

namespace PivotWebsite.Tests.Controllers
{
    [TestClass]
    public class FacetCategoriesControllerTest
    {
        [TestInitialize]
        public void TestInit()
        {
            Utils.TestInit();
        }

        [TestCleanup]
        public void TestCleanup()
        {
            Utils.TestFinalize();
        }

        [TestMethod]
        [ExpectedException(typeof(HttpResponseException))]
        public void GetEmptyNoCollection()
        {
            var c = new FacetCategoriesController();
            var r = c.Get(1);
        }

        [TestMethod]
        public void GetEmpty()
        {
            var cc = new CollectionsController();
            var info = cc.PutCollection("dude");
            var c = new FacetCategoriesController();
            var r = c.Get(info.Id);
            Assert.IsNotNull(r, "response to null fetch");
            Assert.AreEqual(0, r.Length, "number of categories");
        }

        [TestMethod]
        [ExpectedException(typeof(HttpResponseException))]
        public void AddToBadCollection()
        {
            var c = new FacetCategoriesController();
            c.Put(1,
                new FacetCategory[] { new FacetCategory() { IsFilterVisible = true, IsMetaDataVisible = true, IsWordWheelVisible = false, Name = "hi", NumberFormat = "f2" } }
                );
        }

        [TestMethod]
        [ExpectedException(typeof(HttpResponseException))]
        public void AddWithNoFacets()
        {
            var cc = new CollectionsController();
            var info = cc.PutCollection("dude");
            var c = new FacetCategoriesController();
            c.Put(info.Id, null);
        }

        [TestMethod]
        [ExpectedException(typeof(HttpResponseException))]
        public void AddWithNullFacets()
        {
            var cc = new CollectionsController();
            var info = cc.PutCollection("dude");
            var c = new FacetCategoriesController();
            c.Put(info.Id,
                new FacetCategory[] { new FacetCategory() { IsFilterVisible = true, IsMetaDataVisible = true, IsWordWheelVisible = false, Name = null, NumberFormat = "f2" } }
                );
        }

        [TestMethod]
        [ExpectedException(typeof(HttpResponseException))]
        public void AddWithEmptyNameFacets()
        {
            var cc = new CollectionsController();
            var info = cc.PutCollection("dude");
            var c = new FacetCategoriesController();
            c.Put(info.Id,
                new FacetCategory[] { new FacetCategory() { IsFilterVisible = true, IsMetaDataVisible = true, IsWordWheelVisible = false, Name = "", NumberFormat = "f2" } }
                );
        }

        [TestMethod]
        public void AddSingleCategory()
        {
            var cc = new CollectionsController();
            var info = cc.PutCollection("dude");
            var c = new FacetCategoriesController();
            c.Put(info.Id,
                new FacetCategory[] { new FacetCategory() { IsFilterVisible = true, IsMetaDataVisible = true, IsWordWheelVisible = false, Name = "hi", NumberFormat = "f2" } }
                );

            var r = c.Get(info.Id);
            Assert.AreEqual(1, r.Length, "# of facets");
            Assert.AreEqual("hi", r[0].Name, "name of facet");
        }

        [TestMethod]
        public void AddDuplicateFacetCatagory()
        {
            var cc = new CollectionsController();
            var info = cc.PutCollection("dude");
            var c = new FacetCategoriesController();
            c.Put(info.Id,
                new FacetCategory[] { new FacetCategory() { IsFilterVisible = true, IsMetaDataVisible = true, IsWordWheelVisible = false, Name = "hi", NumberFormat = "f2" } }
                );
            c.Put(info.Id,
                new FacetCategory[] { new FacetCategory() { IsFilterVisible = false, IsMetaDataVisible = true, IsWordWheelVisible = false, Name = "hi", NumberFormat = "f2" } }
                );

            var r = c.Get(info.Id);
            Assert.AreEqual(1, r.Length, "# of facets");
            Assert.IsFalse(r[0].IsFilterVisible, "name of facet");
        }

        [TestMethod]
        [DeploymentItem("test.png")]
        public void AddCategoryViaImage()
        {
            var cc = new CollectionsController();
            var info = cc.PutCollection("dude");
            var ic = new ImagesController();
            var iinfo = ic.PutImage(1, "fork", Utils.GetPng());
            var fc = new FacetsController();
            fc.PutFacet(info.Id, iinfo.Id, new FacetAbsBase[] { new FacetString() { Name = "hi", Value = "dude" } });

            var c = new FacetCategoriesController();
            var r = c.Get(info.Id);
            Assert.AreEqual(1, r.Length, "# of facets defined");
            Assert.AreEqual("hi", r[0].Name, "Facet name");
            Assert.AreEqual("", r[0].NumberFormat, "number format");
            Assert.IsTrue(r[0].IsWordWheelVisible, "world wheel");
            Assert.IsTrue(r[0].IsMetaDataVisible, "meta data");
            Assert.IsTrue(r[0].IsFilterVisible, "filter");
        }

        [TestMethod]
        [DeploymentItem("test.png")]
        public void AddCategoryFirstThenImage()
        {
            var cc = new CollectionsController();
            var info = cc.PutCollection("dude");

            var c = new FacetCategoriesController();
            c.Put(info.Id, new FacetCategory[] { new FacetCategory() { Name = "hi", IsFilterVisible = false, IsMetaDataVisible = true, IsWordWheelVisible = true, NumberFormat = "" } });

            var ic = new ImagesController();
            var iinfo = ic.PutImage(1, "fork", Utils.GetPng());
            var fc = new FacetsController();
            fc.PutFacet(info.Id, iinfo.Id, new FacetAbsBase[] { new FacetString() { Name = "hi", Value = "dude" } });

            var r = c.Get(info.Id);
            Assert.AreEqual(1, r.Length, "# of facets defined");
            Assert.AreEqual("hi", r[0].Name, "Facet name");
            Assert.AreEqual("", r[0].NumberFormat, "number format");
            Assert.IsTrue(r[0].IsWordWheelVisible, "world wheel");
            Assert.IsTrue(r[0].IsMetaDataVisible, "meta data");
            Assert.IsFalse(r[0].IsFilterVisible, "filter");
        }

        [TestMethod]
        [DeploymentItem("test.png")]
        public void AddCategoryAfterImage()
        {
            var cc = new CollectionsController();
            var info = cc.PutCollection("dude");

            var ic = new ImagesController();
            var iinfo = ic.PutImage(1, "fork", Utils.GetPng());
            var fc = new FacetsController();
            fc.PutFacet(info.Id, iinfo.Id, new FacetAbsBase[] { new FacetString() { Name = "hi", Value = "dude" } });

            var c = new FacetCategoriesController();
            c.Put(info.Id, new FacetCategory[] { new FacetCategory() { Name = "hi", IsFilterVisible = false, IsMetaDataVisible = true, IsWordWheelVisible = true, NumberFormat = "" } });

            var r = c.Get(info.Id);
            Assert.AreEqual(1, r.Length, "# of facets defined");
            Assert.AreEqual("hi", r[0].Name, "Facet name");
            Assert.AreEqual("", r[0].NumberFormat, "number format");
            Assert.IsTrue(r[0].IsWordWheelVisible, "world wheel");
            Assert.IsTrue(r[0].IsMetaDataVisible, "meta data");
            Assert.IsFalse(r[0].IsFilterVisible, "filter");
        }

        [TestMethod]
        public void DeleteAllCatagories()
        {
            // Delete all facet categories
            var cc = new CollectionsController();
            var info = cc.PutCollection("dude");
            var c = new FacetCategoriesController();
            c.Put(info.Id,
                new FacetCategory[] { new FacetCategory() { IsFilterVisible = true, IsMetaDataVisible = true, IsWordWheelVisible = false, Name = "hi", NumberFormat = "f3" } }
                );

            c.Delete(info.Id);
            var r = c.Get(info.Id);
            Assert.AreEqual(0, r.Length, "# of facets");
        }

        [TestMethod]
        public void DeleteFacet()
        {
            // Delete all facet categories
            var cc = new CollectionsController();
            var info = cc.PutCollection("dude");
            var c = new FacetCategoriesController();
            c.Put(info.Id,
                new FacetCategory[] {
                    new FacetCategory() { IsFilterVisible = true, IsMetaDataVisible = true, IsWordWheelVisible = false, Name = "hi", NumberFormat = "f2" },
                    new FacetCategory() { IsFilterVisible = true, IsMetaDataVisible = true, IsWordWheelVisible = false, Name = "there", NumberFormat = "f2" }
                });

            c.Delete(info.Id, "hi");
            var r = c.Get(info.Id);
            Assert.AreEqual(1, r.Length, "# of facets");
            Assert.AreEqual("there", r[0].Name, "name of leftover facet");
        }

        [TestMethod]
        [ExpectedException(typeof(HttpResponseException))]
        public void DeleteFacetThatDosentExist()
        {
            // Delete all facet categories
            var cc = new CollectionsController();
            var info = cc.PutCollection("dude");
            var c = new FacetCategoriesController();
            c.Delete(info.Id, "hi");
        }

        [TestMethod]
        [ExpectedException(typeof(HttpResponseException))]
        public void DeleteFacetCategoriesForBadCollection()
        {
            var c = new FacetCategoriesController();
            c.Delete(1);
        }

        [TestMethod]
        public void DeleteFacetAlreadyAttachedToImage()
        {
            var cc = new CollectionsController();
            var info = cc.PutCollection("dude");
            var ic = new ImagesController();
            var iinfo = ic.PutImage(1, "fork", Utils.GetPng());
            var fc = new FacetsController();
            fc.PutFacet(info.Id, iinfo.Id, new FacetAbsBase[] { new FacetString() { Name = "hi", Value = "dude" } });

            var c = new FacetCategoriesController();
            c.Delete(info.Id, "hi");
            var r = c.Get(info.Id);
            foreach (var f in r)
            {
                Console.WriteLine("Facet {0} came back", f.Name);
            }
            Assert.AreEqual(1, r.Length, "forced facets");
        }

        [TestMethod]
        public void DeleteFacetReturnsToDefaults()
        {
            var cc = new CollectionsController();
            var info = cc.PutCollection("dude");
            var ic = new ImagesController();
            var iinfo = ic.PutImage(1, "fork", Utils.GetPng());
            var fc = new FacetsController();
            fc.PutFacet(info.Id, iinfo.Id, new FacetAbsBase[] { new FacetString() { Name = "hi", Value = "dude" } });

            var c = new FacetCategoriesController();
            c.Put(info.Id, new FacetCategory[] { new FacetCategory() { Name = "hi", IsFilterVisible = false, IsMetaDataVisible = true, IsWordWheelVisible = true, NumberFormat = "" } });
            c.Delete(info.Id, "hi");
            var r = c.Get(info.Id);
            Assert.IsTrue(r[0].IsFilterVisible, "filter visible should be default");
        }

        [TestMethod]
        public void SetGoodFormatSpecifier()
        {
            // Basically, this should not crash!
            var cc = new CollectionsController();
            var info = cc.PutCollection("dude");
            var c = new FacetCategoriesController();
            c.Put(info.Id,
                new FacetCategory[] {
                    new FacetCategory() { IsFilterVisible = true, IsMetaDataVisible = true, IsWordWheelVisible = false, Name = "hi", NumberFormat = "F2" }
                });
            var r = c.Get(info.Id);
            Assert.AreEqual("F2", r[0].NumberFormat, "Number format");
        }

        [TestMethod]
        [ExpectedException(typeof(HttpResponseException))]
        public void SetBadFormatSpecifier()
        {
            var cc = new CollectionsController();
            var info = cc.PutCollection("dude");
            var c = new FacetCategoriesController();
            c.Put(info.Id,
                new FacetCategory[] {
                    new FacetCategory() { IsFilterVisible = true, IsMetaDataVisible = true, IsWordWheelVisible = false, Name = "hi", NumberFormat = "2F2" }
                });
        }
    }
}
